﻿using AutoMapper;
using BW.WMS.ApiReulst;
using BW.WMS.WareHouseAllot.Doccode;
using BW.WMS.WareHouseAllot.Dto.Goods;
using BW.WMS.WareHouseAllot.Dto.GoodsType;
using BW.WMS.WareHouseAllot.Interface.Doccode;
using BW.WMS.WareHouseAllot.Interface.Goods;
using BW.WMS.WareHouseAllot.Parameter.Input.Goods;
using BW.WMS.WareHouseAllot.Parameter.Output.Goods;
using BW.WMS.WareHouseAllot.Parameter.Output.GoodsType;
using BW.WMS.WareHouseManage;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.ObjectMapping;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace BW.WMS.WareHouseAllot.Goods
{
    /// <summary>
    /// 货品信息实现层
    /// </summary>
    public class GoodsService : ApplicationService, IGoodsService
    {
        private readonly IRepository<GoodsModel> _goodsRepository;
        private readonly IDoccodeService doccodeService;
        private readonly IMapper mapper;
        private readonly IRepository<GoodsTypeModel> _goodsTypeRepository;
        private readonly IRepository<Warehouse> warehouseRepository;

        public GoodsService(IRepository<GoodsModel> GoodsRepository,IDoccodeService doccodeService,IMapper mapper,IRepository<GoodsTypeModel> GoodsTypeRepository,IRepository<Warehouse> WarehouseRepository)
        {
            _goodsRepository = GoodsRepository;
            this.doccodeService = doccodeService;
            this.mapper = mapper;
            _goodsTypeRepository = GoodsTypeRepository;
            warehouseRepository = WarehouseRepository;
        }

        /// <summary>
        /// 添加货品信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<GoodsDto> AddGoods(AddGoodsInput input)
        {
            var goods = ObjectMapper.Map<AddGoodsInput, GoodsModel>(input);

            //调用自动生成编码服务
            goods.GoodsCode= await doccodeService.GenerateCodeAsync("货品信息");
            goods.SumPrice = goods.Inventory * goods.InventoryPrice;
            goods.CreateName = "admin";

            // 检查货品名称和编码的唯一性
            var existingGoodsByName = await _goodsRepository.FirstOrDefaultAsync(x =>
                x.GoodsName == input.GoodsName && !x.IsDeleted);

            if (existingGoodsByName != null)
            {
                throw new UserFriendlyException($"货品名称 '{input.GoodsName}' 已存在，请使用其他名称");
            }

            await _goodsRepository.InsertAsync(goods);

            return ObjectMapper.Map<GoodsModel, GoodsDto>(goods);
        }

        /// <summary>
        /// 获取货品信息数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<GoodsOutput>> GetGoodsList(GoodsQuertInput input)
        {
            // 优化写法：使用IQueryable，在数据库层面过滤
            var goodsQuery = await _goodsRepository.GetQueryableAsync();
            var goods = goodsQuery.Where(x => !x.IsDeleted);

            // 优化写法：使用IQueryable，在数据库层面过滤
            var GoodsTypeQuery = await _goodsTypeRepository.GetQueryableAsync();
            var goodsTypes = GoodsTypeQuery.Where(x => !x.IsDeleted);

            // 优化写法：使用IQueryable，在数据库层面过滤
            var wareHouseQuery = await warehouseRepository.GetQueryableAsync();
            var wareHouse = wareHouseQuery.Where(x => !x.IsDeleted);

            //过滤条件
            if (!string.IsNullOrEmpty(input.GoodsCode))
            {
                goods = goods.Where(x => x.GoodsCode.Equals(input.GoodsCode));
            }
            if (!string.IsNullOrEmpty(input.GoodsName))
            {
                goods = goods.Where(x => x.GoodsName.Contains(input.GoodsName));
            }
            if (input.GoodsTypeId.HasValue)
            {
                goods = goods.Where(x => x.GoodsTypeId == input.GoodsTypeId.Value);
            }

            var linq= from a in goods
                        join b in goodsTypes on a.GoodsTypeId equals b.Id  
                        join c in wareHouse on a.WareHouseId equals c.Id
                      select new GoodsOutput
                        {
                            Id = a.Id,
                            GoodsCode = a.GoodsCode,
                            GoodsName = a.GoodsName,
                            GoodsStatus = a.GoodsStatus,
                            GoodsTypeId = a.GoodsTypeId,
                            WareHouseId=c.Id, // 仓库ID
                            GoodsUnit = a.GoodsUnit,
                            Supplier = a.Supplier,
                            Customer = a.Customer,
                            Sort = a.Sort,
                            InventoryPrice=a.InventoryPrice,
                            OutboundPrice=a.OutboundPrice,
                            Inventory=a.Inventory,
                            SumPrice=a.SumPrice,
                            Lifetime =a.Lifetime,
                            LifetimeManage=a.LifetimeManage,
                            EarlyWarningDays=a.EarlyWarningDays,
                            LastModificationTime = Convert.ToDateTime( a.LastModificationTime),
                            Img= a.Img,
                            File= a.File,
                            GoodsNotes =a.GoodsNotes,
                            CreateName= a.CreateName,
                            GoodsTypeName = b != null ? b.GoodsTypeName : string.Empty, // 关联货品类型名称
                            WareHouseName = c != null ? c.Name : string.Empty // 关联货品类型名称
                        };

            // 4. 排序和分页
            var orderedQuery = linq.OrderBy(x => x.Sort);
            var totalCount = await orderedQuery.CountAsync();
            var items = await orderedQuery
                .Skip(input.SkipCount)
                .Take(input.MaxResultCount)
                .ToListAsync();

            // 5. 返回结果
            return new PagedResultDto<GoodsOutput>(totalCount, items);
        }

        /// <summary>
        /// 根据货品id获取货品信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<GoodsOutput> GetGoodsValue(Guid id)
        {
            // 1. 获取货品信息，包括检查软删除状态
            var goods = await _goodsRepository.GetAsync(x => x.Id == id && !x.IsDeleted);
            if (goods == null)
            {
                throw new UserFriendlyException("货品不存在或已被删除");
            }

            // 2. 获取对应的货品类型信息
            var goodsType = await _goodsTypeRepository.GetAsync(x => x.Id == goods.GoodsTypeId && !x.IsDeleted);
            if (goodsType == null)
            {
                throw new UserFriendlyException("对应的货品类型不存在或已被删除");
            }

            // 3. 使用AutoMapper将实体映射为DTO
            var data = ObjectMapper.Map<GoodsModel, GoodsOutput>(goods);

            // 4. 设置货品类型名称
            data.GoodsTypeName = goodsType.GoodsTypeName;

            return data;
        }

        /// <summary>
        /// 修改货品信息
        /// </summary>
        /// <param name="id"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<GoodsDto> UpdateGoods(Guid id, UpdateGoodsInput input)
        {
            // 【修改1】使用正确的仓储方法
            var goods = await _goodsRepository.GetAsync(x => x.Id == id && !x.IsDeleted);

            if (goods == null)
            {
                // 【修改2】使用ABP框架的异常类型
                throw new UserFriendlyException("货品不存在或已被删除");
            }
            // 【修改3】将输入参数映射到实体
            ObjectMapper.Map(input, goods);

            // 【修改4】更新实体
            await _goodsRepository.UpdateAsync(goods);

            return ObjectMapper.Map<GoodsModel, GoodsDto>(goods);
        }

        /// <summary>
        /// 删除货品信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task DeleteGoods(Guid id)
        {
            // 1. 根据id获取货品信息
            var goods = await _goodsRepository.GetAsync(x => x.Id == id && !x.IsDeleted);

            if (goods == null)
            {
                throw new UserFriendlyException("货品不存在或已被删除");
            }

            // 2. 软删除：设置删除标记
            goods.IsDeleted = true;

            // 4. 保存到数据库
            await _goodsRepository.UpdateAsync(goods);
        }


    }
}
